﻿using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;

namespace Wpc
{
    /**
     * Wpc_操作接口
     */
    [Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
    public interface IComInterface
    {
        // 设置进程文件
        void SetFile(string filename);

        // 设置进程参数
        void SetArgument(string argument);

        // 设置进程域
        void SetDomain(string domain);

        // 设置进程是否带窗口
        void SetNoWindow(bool set);

        // 设置启动进程的用户
        void SetUsername(string username);

        // 设置启动进程的密码
        void SetPassword(string password);

        // 设置进程风格
        void SetStyle(int style);

        // 设置进程工作目录
        void SetWorkDir(string path);

        // 设置待关联进程退出
        bool SetWaitForExit(int timeOut = 1024);

        // 设置指示是否使用操作系统shell启动进程
        void SetUseShellExecute(bool set);

        // 设置进程启动环境变量
        void SetEnvironment(string key, string value);

        // 设置进程重定向标准错误
        void SetRedirectStandardError(bool set);

        // 启动进程
        int Start();

        // 停止进程
        void Stop(int type = 1);

        // 获取进程ID
        int GetPid();

        // 获取进程sessionId
        int GetSessionId();

        // 获取进程名称
        string GetProcessName();

        // 获取进程打开的资源数
        int GetHandleCount();

        // 获取进程主窗口标题
        string GetMainWindowTitle();

        // 获取进程启动时间
        string GetStartTime();

        // 获取进程停止时间
        string GetStopTime();

        // 获取进程标准错误输出
        string GetStandardErrorToEnd();

        // 获取进程是否已经退出
        bool HasExited();
    }

    /**
     * Wpc_事件接口
     */ 
    [Guid("7BD20046-DF8C-44A6-8F6B-687FAA26FA71"),InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IComEvents
    {

    }

    /**
     * Wpc_操作实体
     */
    [Guid("0D53A3E8-E51A-49C7-944E-E72A2064F938"), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(IComEvents))]
    public class Core : IComInterface
    {
        // 进程句柄
        private Process ProcessHand;

        // 构造函数
        public  Core()
        {
            this.ProcessHand = new Process();
        }

        // 设置进程文件
        public void SetFile(string filename)
        {
            this.ProcessHand.StartInfo.FileName = @filename;
        }

        // 设置进程参数
        public void SetArgument(string argument)
        {
            this.ProcessHand.StartInfo.Arguments = argument;
        }

        // 设置进程域
        public void SetDomain(string domain)
        {
            this.ProcessHand.StartInfo.Domain = domain;
        }

        // 设置进程是否带窗口
        public void SetNoWindow(bool set)
        {
            this.ProcessHand.StartInfo.CreateNoWindow = set;
        }

        // 设置启动进程的用户
        public void SetUsername(string username)
        {
            this.ProcessHand.StartInfo.UserName = username;
        }

        // 设置启动进程的密码
        public void SetPassword(string password)
        {
            try
            {
                char[] ch = password.ToCharArray();
                SecureString securePassword = new SecureString();
                foreach (char c in ch)
                {
                    securePassword.AppendChar(c);
                }
                this.ProcessHand.StartInfo.Password = securePassword;
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }

        // 设置进程风格
        public void SetStyle(int style)
        {
            try 
            {
                switch (style)
                {
                    case 0:
                        this.ProcessHand.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
                        break;
                    case 1:
                        this.ProcessHand.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                        break;
                    case 2:
                        this.ProcessHand.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
                        break;
                    case 3:
                        this.ProcessHand.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
                        break;
                    default:
                        this.ProcessHand.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
                        break;
                }
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }

        // 设置进程工作目录
        public void SetWorkDir(string path) {
            if (!Directory.Exists(path))
            {
                throw (new COMException("the directory is not exist:" + path));
            }
            this.ProcessHand.StartInfo.WorkingDirectory = @path;
        }

        // 设置指示是否使用操作系统shell启动进程
        public void SetUseShellExecute (bool set)
        {
            this.ProcessHand.StartInfo.UseShellExecute = set;
        } 

        // 设置进程启动环境变量
        public void SetEnvironment(string key,string value)
        {
            this.ProcessHand.StartInfo.EnvironmentVariables.Add(key, value);
        }

        // 设置进程重定向标准错误
        public void SetRedirectStandardError(bool set) 
        {
            this.ProcessHand.StartInfo.RedirectStandardError = set;
        }

        // 设置待关联进程退出
        public bool SetWaitForExit(int timeOut = 1024) {
            try
            {
                return this.ProcessHand.WaitForExit(timeOut);
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }

        // 启动进程
        public int Start()
        {
            try 
            {
                if (this.ProcessHand.Start())
                {
                    return this.ProcessHand.Id;
                }
                return 0;
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }

        // 停止进程
        public void Stop(int type = 1) 
        {
            try 
            {
                if (type == 1)
                {
                    this.ProcessHand.CloseMainWindow();
                    this.ProcessHand.Close();
                }
                else
                {
                    this.ProcessHand.Kill();
                }
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }

        // 获取进程ID
        public int GetPid()
        {
            return this.ProcessHand.Id;
        }

        // 获取进程sessionId
        public int GetSessionId()
        {
            try
            {
                return ProcessHand.SessionId;
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }

        // 获取进程名称
        public string GetProcessName()
        {
            try
            {
                return this.ProcessHand.ProcessName;
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }

        // 获取进程打开的资源数
        public int GetHandleCount() 
        {
            try
            {
                return this.ProcessHand.HandleCount;
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }

        // 获取进程主窗口标题
        public string GetMainWindowTitle()
        {
            try
            {
                return this.ProcessHand.MainWindowTitle;
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }

        // 获取进程启动时间
        public string GetStartTime()
        { 
            try
            {
                return this.ProcessHand.StartTime.ToString();
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }

        // 获取进程停止时间
        public string GetStopTime()
        {
            try
            {
                return this.ProcessHand.ExitTime.ToString();
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }

        // 获取进程标准错误输出
        public string GetStandardErrorToEnd() 
        {
            return this.ProcessHand.StandardError.ReadToEnd();
        }

        // 获取进程是否已经退出
        public bool HasExited()
        {
            try
            {
                return this.ProcessHand.HasExited;
            }
            catch (Exception exception)
            {
                throw (new COMException(exception.Message));
            }
        }
    }
}
